home *** CD-ROM | disk | FTP | other *** search
- #!/usr/bin/pike
- /* Copyright (C) 2004 Jeroen Dekkers <jeroen@dekkers.cx>
- Copyright (C) 2004 Ben Asselstine <benasselstine@canada.com>
- Copyright (C) 2006 Ying-Chun Liu <grandpaul@gmail.com>
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
-
- /* test case generator 1 */
-
- import Stdio;
-
- int crc32_file(Stdio.File file1) {
- int currentpos;
- int shiftRegister=0;
- string data;
-
- currentpos = file1->tell();
-
- file1->seek(0);
-
- while (1) {
- data = file1->read(1024*8);
- if (data == 0 || strlen(data)==0) {
- break;
- }
- shiftRegister = Gz.crc32(data,shiftRegister);
- }
-
- file1->seek(currentpos);
- return shiftRegister;
- }
-
- string int2bin16 (int d) {
- string ret;
- ret=sprintf("%c%c",
- d%256,
- (d/256)%256);
- return ret;
- }
-
- string int2bin32 (int d) {
- string ret;
- ret=sprintf("%c%c%c%c",
- d%256,
- (d/256)%256,
- (d/256/256)%256,
- (d/256/256/256)%256);
- return ret;
- }
-
- int addfile(string filename1,Stdio.File rarfile) {
- Stdio.File datafile = Stdio.File();
- Stdio.Stat datafile_stat;
- int datafile_crc32,tmp1;
- mapping(string:int) datafile_mtime;
- string datafile_header;
- if (datafile->open(filename1,"r")==0) {
- return 0;
- }
- datafile_stat = datafile->stat();
- datafile_mtime = localtime(datafile_stat->mtime);
- datafile_crc32 = ((crc32_file(datafile)) & 0x0ffffffff);
- /* header: type, flags */
- datafile_header = "\x74\0\x80";
- /* header: header size */
- tmp1 = 32+strlen(filename1);
- datafile_header = datafile_header + int2bin16(tmp1);
- /* header: comp. size, uncomp. size */
- tmp1 = datafile_stat->size;
- datafile_header = datafile_header + int2bin32(tmp1);
- datafile_header = datafile_header + int2bin32(tmp1);
- /* header: OS */
- datafile_header = datafile_header + "\0";
- /* header: File CRC */
- tmp1 = datafile_crc32;
- datafile_header = datafile_header + int2bin32(tmp1);
- /* header: time */
- tmp1 = (datafile_mtime["year"]-80);
- if (tmp1 < 0) tmp1=0;
- tmp1 = tmp1 << 25;
- tmp1 = tmp1 + ((datafile_mtime["mon"]+1)<<21);
- tmp1 = tmp1 + ((datafile_mtime["mday"])<<16);
- tmp1 = tmp1 + ((datafile_mtime["hour"])<<11);
- tmp1 = tmp1 + ((datafile_mtime["min"])<<5);
- tmp1 = tmp1 + ((datafile_mtime["sec"])>>1);
- datafile_header = datafile_header + int2bin32(tmp1);
- /* header: unp. version, method */
- datafile_header = datafile_header + "\x14\x30";
- /* header: filename size */
- tmp1 = strlen(filename1);
- datafile_header = datafile_header + int2bin16(tmp1);
- /* header: file attr. */
- datafile_header = datafile_header + "\x20\0\0\0";
- /* header: filename */
- datafile_header = datafile_header +
- replace(filename1,"/","\\");
- /* header: crc32 */
- tmp1 = ((Gz.crc32(datafile_header)) & 0x0000ffff);
- datafile_header = int2bin16(tmp1) + datafile_header;
- rarfile->write(datafile_header);
- while (1) {
- string datatmp;
- datatmp = datafile->read(1024*8);
- if (datatmp == 0 || strlen(datatmp)==0) {
- break;
- }
- rarfile->write(datatmp);
- }
- datafile->close();
- return 1;
- }
-
- int adddir_header(string filename1,Stdio.File rarfile) {
- int tmp1;
- string datafile_header="";
- Stdio.Stat datafile_stat;
- mapping(string:int) datafile_mtime;
-
- /* header: type, flags */
- datafile_header = "\x74\0\xe0";
- if (has_suffix(filename1, "\\") || has_suffix(filename1,"/")) {
- filename1 = filename1[..strlen(filename1)-2];
- }
-
- tmp1 = 32+strlen(filename1);
- datafile_header += int2bin16(tmp1);
- datafile_header += int2bin32(0);
- datafile_header += int2bin32(0);
- datafile_header += "\0";
- datafile_header += int2bin32(0);
- datafile_stat = file_stat(filename1);
- datafile_mtime = localtime(datafile_stat->mtime);
-
- tmp1 = (datafile_mtime["year"]-80);
- if (tmp1 < 0) tmp1=0;
- tmp1 = tmp1 << 25;
- tmp1 = tmp1 + ((datafile_mtime["mon"]+1)<<21);
- tmp1 = tmp1 + ((datafile_mtime["mday"])<<16);
- tmp1 = tmp1 + ((datafile_mtime["hour"])<<11);
- tmp1 = tmp1 + ((datafile_mtime["min"])<<5);
- tmp1 = tmp1 + ((datafile_mtime["sec"])>>1);
- datafile_header += int2bin32(tmp1);
- datafile_header += "\x14\x30";
- tmp1 = strlen(filename1);
- datafile_header += int2bin16(tmp1);
- datafile_header += "\x10\0\0\0";
- datafile_header +=replace(filename1,"/","\\");
- tmp1 = ((Gz.crc32(datafile_header)) & 0x0000ffff);
- datafile_header = int2bin16(tmp1) + datafile_header;
- rarfile->write(datafile_header);
- }
-
- mapping(string:int) adddir_dirs=([]);
- int adddir(string filename1,Stdio.File rarfile) {
- Filesystem.Traversion ft;
- string filename;
- ft = Filesystem.Traversion(filename1);
- foreach(ft; string dir; string file) {
- if (adddir_dirs[dir] != 1) {
- adddir_header(dir,rarfile);
- adddir_dirs += ([dir:1]);
- }
- filename = dir+file;
- if (is_file(filename)) {
- addfile(filename,rarfile);
- } else if (is_dir(filename)) {
- adddir_header(filename,rarfile);
- }
- }
- }
-
- int main(int argc,array(string) argv) {
- int i,tmp1;
- string filename1;
- Stdio.File rarfile = Stdio.File();
-
- if ( argc < 2 ) {
- write ( "Usage: " + argv[0] + " ARCHIVE [FILE...]\n" );
- return 1;
- }
- if (rarfile->open(argv[1],"wtc")==0) {
- write("Cannot open "+argv[1]+" file\n");
- return 0;
- }
- rarfile->write("Rar!\x1a\x07\0"); /* Marker block */
- rarfile->write("\xcf\x90\x73\0\0\x0d\0\0\0\0\0\0\0"); /* Archive header */
- for (i=2 ; i<argc ; i++) {
- filename1 = argv[i];
- if (is_file(filename1)) {
- addfile(filename1,rarfile);
- } else if (is_dir(filename1)) {
- adddir(filename1,rarfile);
- }
- }
- rarfile->close();
- return 0;
- }
-